home *** CD-ROM | disk | FTP | other *** search
- /*
- * dev.c--
- *
- * Device-dependent manipulations for Sprite Exabyte
- *
- * Copyright 1991 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * Quote:
- * "What a depressingly stupid machine"
- * -- Marvin in _A Hitchiker's Guide to the Galaxy_
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/lib/forms/RCS/dev.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
- #endif /* not lint */
-
- #include <stdio.h>
- #include <sprite.h>
- #include <dev/tape.h>
- #include <dev/robot.h>
- #include <sys/file.h>
- #include <fs.h>
- #include <status.h>
- #include "jaquith.h"
-
- static char printBuf[T_MAXSTRINGLEN];
- extern int syserr;
-
- #define EXB120_MAXBIN 115
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_MoveVolume --
- *
- * Move a volume from source slot to destination slot in jukebox
- *
- * Results:
- * Ptr to block of specified size or NULL;
- *
- * Side effects:
- * Moves robot arm. May also affect volume reader.
- *
- * Note:
- * The tape reader devices in the EXB-120 jukebox are given slot
- * numbers 116-119. If one of these is the destination address
- * a tape load is effectively done.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_MoveVolume(robotStream, src, dest)
- int robotStream; /* robot file descriptor */
- int src; /* source location */
- int dest; /* destination location */
- {
- ReturnStatus status;
- Dev_RobotCommand robotCmd;
-
- robotCmd.sourceAddr = src;
- robotCmd.destAddr = dest;
-
- status = Fs_IOControl(robotStream, IOC_ROBOT_MOVE_MEDIUM,
- sizeof(Dev_RobotCommand), &robotCmd, 0, NULL);
-
- if (status != SUCCESS) {
- syserr = Compat_MapCode(status);
- sprintf(printBuf, "Couldn't move robot: status %d, errno %d",
- status, errno);
- Log_Event("Dev_MoveVolume", printBuf, LOG_FAIL);
- return T_FAILURE;
- }
-
- return T_SUCCESS;
-
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_OpenVolume --
- *
- * Open the device
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_OpenVolume(devName, flags)
- char *devName; /* name of device */
- int flags; /* read, write etc. flags */
- {
- int fd;
-
- if ((fd=open(devName, flags, 0)) == -1) {
- syserr = errno;
- }
- return fd;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_CloseVolume --
- *
- * Close the device
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_CloseVolume(stream)
- int stream; /* file descriptor */
- {
- if (close(stream) == -1) {
- syserr = errno;
- return T_FAILURE;
- } else {
- return T_SUCCESS;
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_ReadVolume --
- *
- * Perform read operation on volume.
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_ReadVolume(volStream, buf, bufSize)
- int volStream;
- char *buf;
- int bufSize;
- {
- int cnt;
-
- if ((cnt=read(volStream, buf, bufSize)) < 0) {
- syserr = errno;
- }
- return cnt;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_WriteVolume --
- *
- * Perform write operation on volume.
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_WriteVolume(volStream, buf, bufSize)
- int volStream;
- char *buf;
- int bufSize;
- {
- int cnt;
-
- if ((cnt=write(volStream, buf, bufSize)) < 0) {
- syserr = errno;
- }
- return cnt;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_UnloadVolume --
- *
- * Open the pod bay door. I'm sorry I can't do that Dave.
- *
- * Results:
- * return code
- *
- * Side effects:
- * Rewinds and unloads tape. Moves robot arm.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_UnloadVolume(devName)
- char *devName; /* device name */
- {
- int volStream;
- Dev_TapeCommand tapeCmd;
- ReturnStatus status;
-
- if ((volStream=open(devName, O_RDONLY, 0)) < 0) {
- syserr = errno;
- return T_FAILURE;
- }
-
- tapeCmd.command = IOC_TAPE_UNLOAD;
- tapeCmd.count = 0;
-
- if ((status=Fs_IOControl(volStream, IOC_TAPE_COMMAND,
- sizeof(Dev_TapeCommand),
- &tapeCmd, 0, NULL)) != SUCCESS) {
- syserr = Compat_MapCode(status);
- close(volStream);
- return T_FAILURE;
- }
- close(volStream);
-
- return T_SUCCESS;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_InitRobot --
- *
- * Initialize robot.
- *
- * Results:
- * return code
- *
- * Side effects:
- * Instructs robot to build database of volume id's
- * using barcode reader.
- *
- * Note:
- * At the moment 'initialization' this means taking
- * tape inventory.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_InitRobot(robotName, robotStreamPtr)
- char *robotName; /* robot device name */
- int *robotStreamPtr; /* robot descriptor */
- {
- if ((*robotStreamPtr=open(robotName, O_RDONLY, 0)) < 0) {
- syserr = errno;
- return T_FAILURE;
- } else {
- return T_SUCCESS;
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_ReadVolLabel --
- *
- * Read volume label with barcode reader
- *
- * Results:
- * return code
- *
- * Side effects:
- * Instructs robot to return element status from its database.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_ReadVolLabel(robotStream, location, volLabel, volIdPtr)
- int robotStream; /* robot descriptor */
- int location; /* home slot in jukebox */
- char *volLabel; /* receiving space for volume label */
- int *volIdPtr; /* receiving space for converted label */
- {
-
- syserr = EINVAL;
- return T_FAILURE;
-
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_CvtVolLabel --
- *
- * Convert character volume label to unique integer.
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- * Note:
- * For present purposes, labels are of the form "<text><number>"
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_CvtVolLabel(volLabel)
- char *volLabel;
- {
- int volId;
- char *workPtr = volLabel+strlen(volLabel)-1;
-
- while ((workPtr >= volLabel) && (isdigit(*workPtr))) {
- workPtr--;
- }
- if ((workPtr >= volLabel) && (sscanf(workPtr+1, "%d", &volId) == 1)) {
- return volId;
- } else {
- return -1;
- }
- }
-
-
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_SeekVolume --
- *
- * Seek to file marker
- *
- * Results:
- * return code
- *
- * Side effects:
- * Instructs tape to seek
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_SeekVolume(volStream, blkId, absolute)
- int volStream; /* volume descriptor */
- int blkId; /* logical file num */
- int absolute; /* absolute positioning flag */
- {
- ReturnStatus status;
- Dev_TapeCommand tapeCmd;
- int oldOffset = 0;
- int retryCnt = 0;
-
- if ((blkId < 0) || (blkId > 10000)) {
- fprintf(stderr,"Dev_SeekVolume: Bad blkId: %d\n", blkId);
- }
-
- if ((volStream < 0) || (volStream > 20)) {
- fprintf(stderr,"Dev_SeekVolume: Bad volStream: %d\n", volStream);
- }
-
- if (absolute) {
- status = Ioc_Reposition(volStream, IOC_BASE_ZERO, 0, &oldOffset);
- /* weird spritism. Give it a retry */
- while ((retryCnt++ < 5) && (status != SUCCESS)) {
- fprintf(stderr, "Rewind failed: status 0x%x. Retrying...\n",
- status);
- sleep(2);
- status = Ioc_Reposition(volStream, IOC_BASE_ZERO,
- 0, &oldOffset);
- }
- if (status != SUCCESS) {
- syserr = Compat_MapCode(status);
- fprintf(stderr, "Couldn't rewind tape. status 0x%x\n",status);
- return T_IOFAILED;
- }
- }
-
- if (blkId > 0) {
- tapeCmd.command = IOC_TAPE_SKIP_FILES;
- tapeCmd.count = blkId;
- status = Fs_IOControl(volStream, IOC_TAPE_COMMAND,
- sizeof(Dev_TapeCommand),
- (Address)&tapeCmd, 0, (Address) 0);
- if (status != SUCCESS) {
- syserr = Compat_MapCode(status);
- fprintf(stderr, "Couldn't skip %d files: 0x%x\n",
- blkId, status);
- return T_IOFAILED;
- }
- }
-
- return T_SUCCESS;
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_WriteEOF --
- *
- * write out EOF
- *
- * Results:
- * return code
- *
- * Side effects:
- * Puts file marker on tape
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_WriteEOF(volStream, count)
- int volStream; /* active stream */
- int count; /* number of marks to write */
- {
- ReturnStatus status;
- Dev_TapeCommand tapeCmd;
-
- tapeCmd.command = IOC_TAPE_WEOF;
- tapeCmd.count = count;
-
- status = Fs_IOControl(volStream, IOC_TAPE_COMMAND,
- sizeof(Dev_TapeCommand),
- (Address)&tapeCmd, 0, (Address) 0);
-
- if (status == DEV_RESET) {
- status = Fs_IOControl(volStream, IOC_TAPE_COMMAND,
- sizeof(Dev_TapeCommand),
- (Address)&tapeCmd, 0, (Address) 0);
- }
-
- if (status == T_SUCCESS) {
- return T_SUCCESS;
- } else {
- syserr = Compat_MapCode(status);
- return T_IOFAILED;
- }
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_GetVolStatus --
- *
- * Inquire into state of volume device
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_GetVolStatus(volStream, volStatusPtr)
- int volStream; /* volume descriptor */
- VolStatus *volStatusPtr; /* receiving structure */
- {
- ReturnStatus status;
- Dev_TapeStatus tapeStatus;
-
- status = Fs_IOControl(volStream, IOC_TAPE_STATUS, 0, NULL,
- sizeof(Dev_TapeStatus), (Address)&tapeStatus);
-
- if (status == DEV_RESET) {
- status = Fs_IOControl(volStream, IOC_TAPE_STATUS, 0, NULL,
- sizeof(Dev_TapeStatus),
- (Address)&tapeStatus);
- }
- if (status == SUCCESS) {
- volStatusPtr->speed = tapeStatus.speed;
- volStatusPtr->density = tapeStatus.density;
- volStatusPtr->remaining = tapeStatus.remaining;
- volStatusPtr->position = tapeStatus.position;
- volStatusPtr->writeProtect = tapeStatus.writeProtect;
- return T_SUCCESS;
- } else {
- syserr = Compat_MapCode(status);
- return T_IOFAILED;
- }
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_DisplayMsg --
- *
- * Display message on jukebox screen
- *
- * Results:
- * return code
- *
- * Side effects:
- * Changes display on robot front panel.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_DisplayMsg(robotStream, msg, msgStyle)
- int robotStream; /* volume descriptor */
- char *msg; /* Message text */
- int msgStyle; /* 0==Steady, 1==flash, 2==scroll */
- {
- ReturnStatus status;
- Dev_RobotCommand robotCmd;
-
- robotCmd.savedPage = 1;
- robotCmd.mesgDisplay = msgStyle;
- robotCmd.mesgString = msg;
- status = Fs_IOControl(robotStream, IOC_ROBOT_DISPLAY,
- sizeof(Dev_RobotCommand),
- &robotCmd, 0, NULL);
-
- if (status != SUCCESS) {
- syserr = Compat_MapCode(status);
- fprintf(printBuf, "Couldn't set display: status %d, errno %d",
- status, syserr);
- return T_FAILURE;
- } else {
- return T_SUCCESS;
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_OpenDoor --
- *
- * Open (or at least unlock) the jukebox door.
- *
- * Results:
- * return code
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_OpenDoor(robotStream)
- int robotStream; /* robot descriptor */
- {
- return T_SUCCESS;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_RemoveVolume --
- *
- * Open (or at least unlock) the jukebox door.
- *
- * Results:
- * return code
- *
- * Side effects:
- * Kicks a volume out of archive.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_RemoveVolume(robotStream, src)
- int robotStream; /* robot descriptor */
- int src; /* src slot location */
- {
- ReturnStatus status;
- Dev_RobotCommand robotCmd;
-
- robotCmd.sourceAddr = src;
- robotCmd.destAddr = 120; /* slot id of entry/exit port */
- robotCmd.eePos = 0x40; /* spit volume out to user */
-
- status = Fs_IOControl(robotStream, IOC_ROBOT_MOVE_MEDIUM,
- sizeof(Dev_RobotCommand), &robotCmd, 0, NULL);
-
- if (status != SUCCESS) {
- syserr = Compat_MapCode(status);
- sprintf(printBuf, "Couldn't remove volume: status %d, errno %d",
- status, errno);
- Log_Event("Dev_RemoveVolume", printBuf, LOG_FAIL);
- return T_FAILURE;
- }
-
- return T_SUCCESS;
-
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_InsertVolume --
- *
- * Open (or at least unlock) the jukebox door.
- *
- * Results:
- * return code
- *
- * Side effects:
- * Pull in a new volume.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_InsertVolume(robotStream, dest)
- int robotStream; /* robot descriptor */
- int dest; /* destination slot location */
- {
- ReturnStatus status;
- Dev_RobotCommand robotCmd;
-
- robotCmd.sourceAddr = 120; /* slot id of entry/exit port */
- robotCmd.destAddr = dest;
- robotCmd.eePos = 0x80; /* suck volume in from user */
-
- status = Fs_IOControl(robotStream, IOC_ROBOT_MOVE_MEDIUM,
- sizeof(Dev_RobotCommand), &robotCmd, 0, NULL);
-
- if (status != SUCCESS) {
- syserr = Compat_MapCode(status);
- sprintf(printBuf, "Couldn't insert volume: status %d, errno %d",
- status, errno);
- Log_Event("Dev_InsertVolume", printBuf, LOG_FAIL);
- return T_FAILURE;
- }
-
- return T_SUCCESS;
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Dev_BuildVolList --
- *
- * Build a list of jukebox's contents
- *
- * Results:
- * return code
- *
- * Side effects:
- * none.
- *
- *----------------------------------------------------------------------
- */
-
- int
- Dev_BuildVolList(robotStream, listPtr, cntPtr)
- int robotStream; /* robot descriptor */
- VolConfig *listPtr; /* space for volume info */
- int *cntPtr; /* size of list */
-
- {
- int i;
- int cnt = 0;
- int maxBin = EXB120_MAXBIN+1;
- int retCode = T_SUCCESS;
- char label[T_MAXLABELLEN];
-
- if (*cntPtr < maxBin) {
- syserr = ENOSPC;
- *cntPtr = EXB120_MAXBIN+1;
- return T_FAILURE;
- }
-
- for (i=0; i<maxBin; i++) {
- if ((retCode=Dev_ReadVolLabel(robotStream, i, label)) != T_SUCCESS) {
- *cntPtr = 0;
- return retCode;
- }
- listPtr->volId = i;
- listPtr->location = i;
- strcpy(listPtr->volLabel, label);
- listPtr++;
- cnt++;
- }
-
- *cntPtr = cnt;
- return T_SUCCESS;
-
- }
-